package org.lease.service.impl;


import io.minio.*;
import io.minio.errors.*;
import org.lease.model.props.MinioProperties;
import org.lease.service.FileUploadService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

@Service
public class FileUploadServiceImpl implements FileUploadService {
    @Autowired
    private MinioProperties prop;

    @Autowired
    private MinioClient minioClient;

    @Override
    public String upload(MultipartFile file) throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        // 判断 Bucket 是否存在
        BucketExistsArgs existsArgs = BucketExistsArgs.builder().bucket(prop.getBucketName()).build();
        boolean exist = minioClient.bucketExists(existsArgs);
        if (!exist) {
            // - 创建 Bucket
            MakeBucketArgs makeBucketArgs = MakeBucketArgs.builder().bucket(prop.getBucketName()).build();
            minioClient.makeBucket(makeBucketArgs);
            // - 设置 Bucket 权限
            SetBucketPolicyArgs bucketPolicyArgs = SetBucketPolicyArgs.builder().bucket(prop.getBucketName()).config(createBucketPolicyConfig(prop.getBucketName())).build();
            minioClient.setBucketPolicy(bucketPolicyArgs);
        }

        // 上传文件
        String filename = new SimpleDateFormat("yyyyMMdd").format(new Date()) + "/" + UUID.randomUUID() + "-" + file.getOriginalFilename();
        PutObjectArgs putObjectArgs = PutObjectArgs.builder().bucket(prop.getBucketName()).object(filename).stream(file.getInputStream(), file.getSize(), -1).contentType(file.getContentType()).build();
        minioClient.putObject(putObjectArgs);

        // 返回上传后的文件路径
        return String.join("/", prop.getEndpoint(), prop.getBucketName(), filename);
    }

    private String createBucketPolicyConfig(String bucketName) {
        return """
                {
                  "Statement" : [ {
                    "Action" : "s3:GetObject",
                    "Effect" : "Allow",
                    "Principal" : "*",
                    "Resource" : "arn:aws:s3:::%s/*"
                  } ],
                  "Version" : "2012-10-17"
                }
                """.formatted(bucketName);
    }
}
